home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Personal Computer World 2009 February
/
PCWFEB09.iso
/
Software
/
Resources
/
Chat & Communication
/
Digsby build 37
/
digsby_setup.exe
/
lib
/
dns
/
message.pyo
(
.txt
)
< prev
next >
Wrap
Python Compiled Bytecode
|
2008-10-13
|
19KB
|
728 lines
# Source Generated with Decompyle++
# File: in.pyo (Python 2.5)
import cStringIO
import random
import struct
import sys
import time
import dns.exception as dns
import dns.flags as dns
import dns.name as dns
import dns.opcode as dns
import dns.rcode as dns
import dns.rdata as dns
import dns.rdataclass as dns
import dns.rdatatype as dns
import dns.rrset as dns
import dns.renderer as dns
import dns.tsig as dns
class ShortHeader(dns.exception.FormError):
pass
class TrailingJunk(dns.exception.FormError):
pass
class UnknownHeaderField(dns.exception.DNSException):
pass
class BadEDNS(dns.exception.FormError):
pass
class BadTSIG(dns.exception.FormError):
pass
class UnknownTSIGKey(dns.exception.DNSException):
pass
class Message(object):
def __init__(self, id = None):
if id is None:
self.id = random.randint(0, 65535)
else:
self.id = id
self.flags = 0
self.question = []
self.answer = []
self.authority = []
self.additional = []
self.edns = -1
self.ednsflags = 0
self.payload = 0
self.request_payload = 0
self.keyring = None
self.keyname = None
self.request_mac = ''
self.other_data = ''
self.tsig_error = 0
self.fudge = 300
self.original_id = self.id
self.mac = ''
self.xfr = False
self.origin = None
self.tsig_ctx = None
self.had_tsig = False
self.multi = False
self.first = True
self.index = { }
def __repr__(self):
return '<DNS message, ID ' + `self.id` + '>'
def __str__(self):
return self.to_text()
def to_text(self, origin = None, relativize = True, **kw):
s = cStringIO.StringIO()
print >>s, 'id %d' % self.id
print >>s, 'opcode %s' % dns.opcode.to_text(dns.opcode.from_flags(self.flags))
rc = dns.rcode.from_flags(self.flags, self.ednsflags)
print >>s, 'rcode %s' % dns.rcode.to_text(rc)
print >>s, 'flags %s' % dns.flags.to_text(self.flags)
if self.edns >= 0:
print >>s, 'edns %s' % self.edns
if self.ednsflags != 0:
print >>s, 'eflags %s' % dns.flags.edns_to_text(self.ednsflags)
print >>s, 'payload', self.payload
is_update = dns.opcode.is_update(self.flags)
if is_update:
print >>s, ';ZONE'
else:
print >>s, ';QUESTION'
for rrset in self.question:
print >>s, rrset.to_text(origin, relativize, **kw)
if is_update:
print >>s, ';PREREQ'
else:
print >>s, ';ANSWER'
for rrset in self.answer:
print >>s, rrset.to_text(origin, relativize, **kw)
if is_update:
print >>s, ';UPDATE'
else:
print >>s, ';AUTHORITY'
for rrset in self.authority:
print >>s, rrset.to_text(origin, relativize, **kw)
print >>s, ';ADDITIONAL'
for rrset in self.additional:
print >>s, rrset.to_text(origin, relativize, **kw)
return s.getvalue()[:-1]
def __eq__(self, other):
if not isinstance(other, Message):
return False
if self.id != other.id:
return False
if self.flags != other.flags:
return False
for n in self.question:
if n not in other.question:
return False
continue
for n in other.question:
if n not in self.question:
return False
continue
for n in self.answer:
if n not in other.answer:
return False
continue
for n in other.answer:
if n not in self.answer:
return False
continue
for n in self.authority:
if n not in other.authority:
return False
continue
for n in other.authority:
if n not in self.authority:
return False
continue
return True
def __ne__(self, other):
return not self.__eq__(other)
def is_response(self, other):
if other.flags & dns.flags.QR == 0 and self.id != other.id or dns.opcode.from_flags(self.flags) != dns.opcode.from_flags(other.flags):
return False
if dns.rcode.from_flags(other.flags, other.ednsflags) != dns.rcode.NOERROR:
return True
if dns.opcode.is_update(self.flags):
return True
for n in self.question:
if n not in other.question:
return False
continue
for n in other.question:
if n not in self.question:
return False
continue
return True
def section_number(self, section):
if section is self.question:
return 0
elif section is self.answer:
return 1
elif section is self.authority:
return 2
elif section is self.additional:
return 3
else:
raise ValueError, 'unknown section'
def find_rrset(self, section, name, rdclass, rdtype, covers = dns.rdatatype.NONE, deleting = None, create = False, force_unique = False):
key = (self.section_number(section), name, rdclass, rdtype, covers, deleting)
if not force_unique:
if self.index is not None:
rrset = self.index.get(key)
if rrset is not None:
return rrset
else:
for rrset in section:
if rrset.match(name, rdclass, rdtype, covers, deleting):
return rrset
continue
if not create:
raise KeyError
rrset = dns.rrset.RRset(name, rdclass, rdtype, covers, deleting)
section.append(rrset)
if self.index is not None:
self.index[key] = rrset
return rrset
def get_rrset(self, section, name, rdclass, rdtype, covers = dns.rdatatype.NONE, deleting = None, create = False, force_unique = False):
try:
rrset = self.find_rrset(section, name, rdclass, rdtype, covers, deleting, create, force_unique)
except KeyError:
rrset = None
return rrset
def to_wire(self, origin = None, max_size = 0, **kw):
if max_size == 0:
if self.request_payload != 0:
max_size = self.request_payload
else:
max_size = 65535
if max_size < 512:
max_size = 512
elif max_size > 65535:
max_size = 65535
r = dns.renderer.Renderer(self.id, self.flags, max_size, origin)
for rrset in self.question:
r.add_question(rrset.name, rrset.rdtype, rrset.rdclass)
for rrset in self.answer:
r.add_rrset(dns.renderer.ANSWER, rrset, **kw)
for rrset in self.authority:
r.add_rrset(dns.renderer.AUTHORITY, rrset, **kw)
if self.edns >= 0:
r.add_edns(self.edns, self.ednsflags, self.payload)
for rrset in self.additional:
r.add_rrset(dns.renderer.ADDITIONAL, rrset, **kw)
r.write_header()
if self.keyname is not None:
r.add_tsig(self.keyname, self.keyring[self.keyname], self.fudge, self.original_id, self.tsig_error, self.other_data, self.request_mac)
self.mac = r.mac
return r.get_wire()
def use_tsig(self, keyring, keyname = None, fudge = 300, original_id = None, tsig_error = 0, other_data = ''):
self.keyring = keyring
if keyname is None:
self.keyname = self.keyring.keys()[0]
elif isinstance(keyname, (str, unicode)):
keyname = dns.name.from_text(keyname)
self.keyname = keyname
self.fudge = fudge
if original_id is None:
self.original_id = self.id
else:
self.original_id = original_id
self.tsig_error = tsig_error
self.other_data = other_data
def use_edns(self, edns = 0, ednsflags = 0, payload = 1280, request_payload = None):
if edns is None or edns is False:
edns = -1
if edns is True:
edns = 0
if request_payload is None:
request_payload = payload
if edns < 0:
ednsflags = 0
payload = 0
request_payload = 0
else:
ednsflags &= 0xFF00FFFFL
ednsflags |= edns << 16
self.edns = edns
self.ednsflags = ednsflags
self.payload = payload
self.request_payload = request_payload
def want_dnssec(self, wanted = True):
if wanted:
if self.edns < 0:
self.use_edns()
self.ednsflags |= dns.flags.DO
elif self.edns >= 0:
self.ednsflags &= ~(dns.flags.DO)
def rcode(self):
return dns.rcode.from_flags(self.flags, self.ednsflags)
def set_rcode(self, rcode):
(value, evalue) = dns.rcode.to_flags(rcode)
self.flags &= 65520
self.flags |= value
self.ednsflags &= 0xFFFFFFL
self.ednsflags |= evalue
def opcode(self):
return dns.opcode.from_flags(self.flags)
def set_opcode(self, opcode):
self.flags &= 34815
self.flags |= dns.opcode.to_flags(opcode)
class _WireReader(object):
def __init__(self, wire, message, question_only = False):
self.wire = wire
self.message = message
self.current = 0
self.updating = False
self.zone_rdclass = dns.rdataclass.IN
self.question_only = question_only
def _get_question(self, qcount):
if self.updating and qcount > 1:
raise dns.exception.FormError
for i in xrange(0, qcount):
(qname, used) = dns.name.from_wire(self.wire, self.current)
if self.message.origin is not None:
qname = qname.relativize(self.message.origin)
self.current = self.current + used
(rdtype, rdclass) = struct.unpack('!HH', self.wire[self.current:self.current + 4])
self.current = self.current + 4
self.message.find_rrset(self.message.question, qname, rdclass, rdtype, create = True, force_unique = True)
if self.updating:
self.zone_rdclass = rdclass
continue
def _get_section(self, section, count):
if self.updating:
force_unique = True
else:
force_unique = False
seen_opt = False
for i in xrange(0, count):
rr_start = self.current
(name, used) = dns.name.from_wire(self.wire, self.current)
if self.message.origin is not None:
name = name.relativize(self.message.origin)
self.current = self.current + used
(rdtype, rdclass, ttl, rdlen) = struct.unpack('!HHIH', self.wire[self.current:self.current + 10])
self.current = self.current + 10
if rdtype == dns.rdatatype.OPT:
if section is not self.message.additional or seen_opt:
raise BadEDNS
self.message.payload = rdclass
self.message.ednsflags = ttl
self.message.edns = (ttl & 16711680) >> 16
seen_opt = True
elif rdtype == dns.rdatatype.TSIG:
if not section is self.message.additional and i == count - 1:
raise BadTSIG
if self.message.keyring is None:
raise UnknownTSIGKey, 'got signed message without keyring'
secret = self.message.keyring.get(name)
if secret is None:
raise UnknownTSIGKey, "key '%s' unknown" % name
self.message.tsig_ctx = dns.tsig.validate(self.wire, name, secret, int(time.time()), self.message.request_mac, rr_start, self.current, rdlen, self.message.tsig_ctx, self.message.multi, self.message.first)
self.message.had_tsig = True
elif ttl < 0:
ttl = 0
if self.updating:
if rdclass == dns.rdataclass.ANY or rdclass == dns.rdataclass.NONE:
deleting = rdclass
rdclass = self.zone_rdclass
else:
deleting = None
if deleting == dns.rdataclass.ANY:
covers = dns.rdatatype.NONE
rd = None
else:
rd = dns.rdata.from_wire(rdclass, rdtype, self.wire, self.current, rdlen, self.message.origin)
covers = rd.covers()
if self.message.xfr and rdtype == dns.rdatatype.SOA:
force_unique = True
rrset = self.message.find_rrset(section, name, rdclass, rdtype, covers, deleting, True, force_unique)
if rd is not None:
rrset.add(rd, ttl)
self.current = self.current + rdlen
def read(self):
l = len(self.wire)
if l < 12:
raise ShortHeader
(self.message.id, self.message.flags, qcount, ancount, aucount, adcount) = struct.unpack('!HHHHHH', self.wire[:12])
self.current = 12
if dns.opcode.is_update(self.message.flags):
self.updating = True
self._get_question(qcount)
if self.question_only:
return None
self._get_section(self.message.answer, ancount)
self._get_section(self.message.authority, aucount)
self._get_section(self.message.additional, adcount)
if self.current != l:
raise TrailingJunk
if self.message.multi and self.message.tsig_ctx and not (self.message.had_tsig):
self.message.tsig_ctx.update(self.wire)
def from_wire(wire, keyring = None, request_mac = '', xfr = False, origin = None, tsig_ctx = None, multi = False, first = True, question_only = False):
m = Message(id = 0)
m.keyring = keyring
m.request_mac = request_mac
m.xfr = xfr
m.origin = origin
m.tsig_ctx = tsig_ctx
m.multi = multi
m.first = first
reader = _WireReader(wire, m, question_only)
reader.read()
return m
class _TextReader(object):
def __init__(self, text, message):
self.message = message
self.tok = dns.tokenizer.Tokenizer(text)
self.last_name = None
self.zone_rdclass = dns.rdataclass.IN
self.updating = False
def _header_line(self, section):
(ttype, what) = self.tok.get()
if what == 'id':
self.message.id = self.tok.get_int()
elif what == 'flags':
while True:
token = self.tok.get()
if token[0] != dns.tokenizer.IDENTIFIER:
self.tok.unget(token)
break
self.message.flags = self.message.flags | dns.flags.from_text(token[1])
if dns.opcode.is_update(self.message.flags):
self.updating = True
elif what == 'edns':
self.message.edns = self.tok.get_int()
self.message.ednsflags = self.message.ednsflags | self.message.edns << 16
elif what == 'eflags':
if self.message.edns < 0:
self.message.edns = 0
while True:
token = self.tok.get()
if token[0] != dns.tokenizer.IDENTIFIER:
self.tok.unget(token)
break
self.message.ednsflags = self.message.ednsflags | dns.flags.edns_from_text(token[1])
elif what == 'payload':
self.message.payload = self.tok.get_int()
if self.message.edns < 0:
self.message.edns = 0
elif what == 'opcode':
text = self.tok.get_string()
self.message.flags = self.message.flags | dns.opcode.to_flags(dns.opcode.from_text(text))
elif what == 'rcode':
text = self.tok.get_string()
self.message.set_rcode(dns.rcode.from_text(text))
else:
raise UnknownHeaderField
self.tok.get_eol()
def _question_line(self, section):
token = self.tok.get(want_leading = True)
if token[0] != dns.tokenizer.WHITESPACE:
self.last_name = dns.name.from_text(token[1], None)
name = self.last_name
token = self.tok.get()
if token[0] != dns.tokenizer.IDENTIFIER:
raise dns.exception.SyntaxError
try:
rdclass = dns.rdataclass.from_text(token[1])
token = self.tok.get()
if token[0] != dns.tokenizer.IDENTIFIER:
raise dns.exception.SyntaxError
except dns.exception.SyntaxError:
raise dns.exception.SyntaxError
except:
rdclass = dns.rdataclass.IN
rdtype = dns.rdatatype.from_text(token[1])
self.message.find_rrset(self.message.question, name, rdclass, rdtype, create = True, force_unique = True)
if self.updating:
self.zone_rdclass = rdclass
self.tok.get_eol()
def _rr_line(self, section):
deleting = None
token = self.tok.get(want_leading = True)
if token[0] != dns.tokenizer.WHITESPACE:
self.last_name = dns.name.from_text(token[1], None)
name = self.last_name
token = self.tok.get()
if token[0] != dns.tokenizer.IDENTIFIER:
raise dns.exception.SyntaxError
try:
ttl = int(token[1], 0)
token = self.tok.get()
if token[0] != dns.tokenizer.IDENTIFIER:
raise dns.exception.SyntaxError
except dns.exception.SyntaxError:
raise dns.exception.SyntaxError
except:
ttl = 0
try:
rdclass = dns.rdataclass.from_text(token[1])
token = self.tok.get()
if token[0] != dns.tokenizer.IDENTIFIER:
raise dns.exception.SyntaxError
if rdclass == dns.rdataclass.ANY or rdclass == dns.rdataclass.NONE:
deleting = rdclass
rdclass = self.zone_rdclass
except dns.exception.SyntaxError:
raise dns.exception.SyntaxError
except:
rdclass = dns.rdataclass.IN
rdtype = dns.rdatatype.from_text(token[1])
token = self.tok.get()
if token[0] != dns.tokenizer.EOL and token[0] != dns.tokenizer.EOF:
self.tok.unget(token)
rd = dns.rdata.from_text(rdclass, rdtype, self.tok, None)
covers = rd.covers()
else:
rd = None
covers = dns.rdatatype.NONE
rrset = self.message.find_rrset(section, name, rdclass, rdtype, covers, deleting, True, self.updating)
if rd is not None:
rrset.add(rd, ttl)
def read(self):
line_method = self._header_line
section = None
while None:
token = self.tok.get(True, True)
if token[0] == dns.tokenizer.EOL or token[0] == dns.tokenizer.EOF:
break
if token[0] == dns.tokenizer.COMMENT:
u = token[1].upper()
if u == 'HEADER':
line_method = self._header_line
elif u == 'QUESTION' or u == 'ZONE':
line_method = self._question_line
section = self.message.question
elif u == 'ANSWER' or u == 'PREREQ':
line_method = self._rr_line
section = self.message.answer
elif u == 'AUTHORITY' or u == 'UPDATE':
line_method = self._rr_line
section = self.message.authority
elif u == 'ADDITIONAL':
line_method = self._rr_line
section = self.message.additional
self.tok.get_eol()
continue
line_method(section)
continue
return None
def from_text(text):
m = Message()
reader = _TextReader(text, m)
reader.read()
return m
def from_file(f):
if sys.hexversion >= 33751040:
str_type = basestring
opts = 'rU'
else:
str_type = str
opts = 'r'
if isinstance(f, str_type):
f = file(f, opts)
want_close = True
else:
want_close = False
try:
m = from_text(f)
finally:
if want_close:
f.close()
return m
def make_query(qname, rdtype, rdclass = dns.rdataclass.IN, use_edns = None, want_dnssec = False):
if isinstance(qname, (str, unicode)):
qname = dns.name.from_text(qname)
if isinstance(rdtype, str):
rdtype = dns.rdatatype.from_text(rdtype)
if isinstance(rdclass, str):
rdclass = dns.rdataclass.from_text(rdclass)
m = Message()
m.flags |= dns.flags.RD
m.find_rrset(m.question, qname, rdclass, rdtype, create = True, force_unique = True)
m.use_edns(use_edns)
m.want_dnssec(want_dnssec)
return m
def make_response(query, recursion_available = False, our_payload = 8192):
if query.flags & dns.flags.QR:
raise dns.exception.FormError, 'specified query message is not a query'
response = dns.message.Message(query.id)
response.flags = dns.flags.QR | query.flags & dns.flags.RD
if recursion_available:
response.flags |= dns.flags.RA
response.set_opcode(query.opcode())
response.question = list(query.question)
if query.edns >= 0:
response.use_edns(0, 0, our_payload, query.payload)
if query.keyname is not None:
response.keyname = query.keyname
response.keyring = query.keyring
response.request_mac = query.mac
return response